package com.lagou.edu.factory;

import com.lagou.edu.annotation.MyAnnotation;
import com.lagou.edu.scan.ClasspathPackageScanner;
import com.lagou.edu.scan.PackageScanner;

import java.io.IOException;
import com.lagou.edu.annotation.MyAnnotation.Service;
import com.lagou.edu.annotation.MyAnnotation.Autowired;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/*
 * 工厂类 生产对象
 */
public class BeanFactory {



    private static Map<String, Object> map = new HashMap<>();

    static {
        // 1. scan对应包下的文件,通过反射技术实例化对象并存储待用(map)
        // 扫描包

        PackageScanner scan = new ClasspathPackageScanner("com.lagou.edu");
        try {
            List<String> fullyQualifiedClassNameList = scan.getFullyQualifiedClassNameList();
            for (int i = 0; i < fullyQualifiedClassNameList.size(); i++) {
                String clazz =  fullyQualifiedClassNameList.get(i);
                // 通过反射技术实例化对象
                Class<?> aClass = Class.forName(clazz);
                Service annotationService = aClass.getAnnotation(Service.class);
                if(annotationService != null) {
                    Object o = aClass.newInstance();
                    String id = annotationService.value();
                    map.put(id, o);
                }
            }

            for (int i = 0; i < fullyQualifiedClassNameList.size(); i++) {
                String clazz =  fullyQualifiedClassNameList.get(i);
                // 通过反射技术实例化对象
                Class<?> aClass = Class.forName(clazz);
                Service annotationService = aClass.getAnnotation(Service.class);
                if(annotationService != null) {
                    Object o = aClass.newInstance();
                    Field[] declaredFields = aClass.getDeclaredFields();
                    for (int j = 0; j < declaredFields.length; j++) {
                        Field field =  declaredFields[j];
                        Autowired annotationAutowired = field.getAnnotation(Autowired.class);
                        if(annotationAutowired != null) {
                            field.setAccessible(true);
                            field.set(o, map.get(field.getName()));
                        }
                    }
                    String id = annotationService.value();
                    map.put(id, o);
                }
            }
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }

    }

    // 2.对外提供获取实例对象的接口(根据id获取)
    public static Object getBean(String id) {
        return map.get(id);
    }
}
